#ifndef MYTCPSOCKET_H
#define MYTCPSOCKET_H

#include <QObject>
#include <QTcpSocket>
#include <QProcess>
#include "publicstruct.h"

class MyTcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
    explicit MyTcpSocket(QObject *parent = nullptr):QTcpSocket(parent){
        // new 分配空间时调用构造  git-log里面描述错了(那里描述静态成员变量初始化不执行构造函数)
        //qDebug()<<"MyTcpSocket 构造调用";
    }
signals:
    void jsonRecv(QString);
};



//全局对象，里面包含全局唯一的通讯socket等 懒汉单例 线程不安全(指多个线程同时访问,要进行判断是否为空,初始化等操作)
//但在这里,客户端一开始是单线程的,确保已经被实例化,多个线程读到的实例一定不为空,不会再次初始化
class GlobalObject:public QObject
{
    Q_OBJECT
private:
    explicit GlobalObject(QObject *parent = nullptr);
public:
    // 从好友列表中,删除好友
    void deleteFriendFromList(int fuid);
    // 从群聊列表，删除列表
    void deleteGroupFromList(int gid);
    // 改变好友链表中好友的状态
    void updateFriendStatus(int fuid,int status);
    // 根据好友UID获取好友个人资料
    struct st_friendData getFriendInfo(int fuid);
    // 根据群ID获取群资料
    struct st_gData getGroupInfo(int gid);
    // 发送请求
    void sendRequest(QVariantMap map);
    void sendRequest(QByteArray bytes);
    // 上传文件到服务器
    void uploadToServer(const QString& localpath,const QString& srvpath);
    // 下载文件到本地
    void downloadToLocal(const QString& srvpath,const QString& localpath);

    // 上传文件到服务器(小文件,不需要文件ID以及完整性检测)
    void uploadToServer_Small(const QString& localpath,const QString& srvpath);


    static GlobalObject* getGlobalObject();

    MyTcpSocket *getTcpsocket() const;

    st_userInfo getUserInfo() const;
    void setUserInfo(st_userInfo newUserInfo);
    void insertGroupElement(struct st_gData gdata);
    void insertFriendElement(struct st_friendData fdata);

    int getCurrentSelectUid() const;
    void setCurrentSelectUid(int newCurrentSelectUid);

    int getCurrentSendFileUid() const;
    void setCurrentSendFileUid(int newCurrentSendFileUid);

    QString getSendfilePath() const;
    void setSendfilePath(const QString &newSendfilePath);


    QMap<int, QString> getMapJoy() const;

    QString getUploadFileID() const;
    void setUploadFileID(const QString &newUploadFileID);

    int getCurrentSelectGid() const;
    void setCurrentSelectGid(int newCurrentSelectGid);


    int getCurrentSendFileGid() const;
    void setCurrentSendFileGid(int newCurrentSendFileGid);

    int getUpload_file_flag() const;
    void setUpload_file_flag(int newUpload_file_flag);

    QString getSaveFileLocalPath() const;
    void setSaveFileLocalPath(const QString &newSaveFileLocalPath);

    QString getSaveFileSrvPath() const;
    void setSaveFileSrvPath(const QString &newSaveFileSrvPath);

private:
    static GlobalObject* globalObject;    // 全局对象
    MyTcpSocket* tcpsocket;               // 静态对象属于类,不能在定义对象时初始化,new时调用构造
    struct st_userInfo userInfo;          // 用户信息的全局访问接口
    int currentSelectUid;                // 当前好友列表选择用户的UID
    int currentSelectGid;                // 当前群列表选择的群ID

    int currentSendFileUid;              // 当前发送文件的好友ID
    int currentSendFileGid;              // 当前发送文件的群ID
    int upload_file_flag;                // 判断当前是上传私聊文件还是群文件的标志  1-私聊文件  2-群文件 3-动态图片

    QString sendfilePath;                // 发送本地文件选择的路径
    QString uploadFileID;                // 上传文件的文件ID
    QString saveFileLocalPath;          // 文件保存的本地路径
    QString saveFileSrvPath;            // 文件保存的服务器路径(减少一些解析) http://%1:8080/file...


    QMap<int,QString> mapJoy;            // 表情map
    //long global_syncPos;                // 全局同步位点,每次从同步TimeLine拉取消息后需要更新,客户端下线需要持久化到文件

private slots:
    // 处理标准输出
    void readStandardOutput();
    // 处理标准错误
    void readStandardError();
    // 处理文件上传进程结束
    void uploadProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
    // 处理文件上传进程结束(小文件)
    void uploadProcessFinished_Small(int exitCode, QProcess::ExitStatus exitStatus);
    // 处理文件下载进程结束
    void downloadProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);


};

#endif // MYTCPSOCKET_H
